package com.dofun.locationservice.ui.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Message;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;

import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.Polyline;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.dofun.locationservice.MsgObservable;
import com.dofun.locationservice.R;
import com.dofun.locationservice.RunConstants;
import com.dofun.locationservice.base.BaseActivity;
import com.dofun.locationservice.base.IBasePresenter;
import com.dofun.locationservice.bean.Information;
import com.dofun.locationservice.biz.main.IMainView;
import com.dofun.locationservice.biz.main.MainPresenter;
import com.dofun.locationservice.service.WorkService;
import com.dofun.locationservice.util.L;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.util.LinkedList;
import java.util.Observable;
import java.util.Observer;

import butterknife.BindView;
import butterknife.OnClick;

import static com.dofun.locationservice.base.BaseApplication.showToast;


public class MainActivity extends BaseActivity
        implements NavigationView.OnNavigationItemSelectedListener, IMainView, Observer {

    @BindView(R.id.toolbar)
    Toolbar toolbar;
    @BindView(R.id.nav_view)
    NavigationView navigationView;
    @BindView(R.id.drawer_layout)
    DrawerLayout drawer;
    @BindView(R.id.appbar)
    AppBarLayout appbar;
    @BindView(R.id.mapView)
    MapView mapView;
    @BindView(R.id.iv_location)
    ImageView ivLocation;

    private MainPresenter mainPresenter;
    private BaiduMap mBaiduMap;
    private SDKReceiver mReceiver;

    private LinkedList<LatLng> mPointListWithGps = new LinkedList<>();
    private LinkedList<MyLocationData> mMoveGpsDataList = new LinkedList<>();

    @Override
    protected IBasePresenter[] getPresenterArray() {
        mainPresenter = new MainPresenter();
        return new IBasePresenter[]{mainPresenter};
    }

    @Override
    protected int getContentViewId() {
        return R.layout.activity_main;
    }

    @Override
    protected void initBundleData() {
    }

    @Override
    protected void initView(Bundle savedInstanceState) {
        setTitle("Dofun Location Service");
        setSupportActionBar(toolbar);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        navigationView.setNavigationItemSelectedListener(this);
        initMapView(this, savedInstanceState);
    }

    @Override
    protected void initData() {
        MsgObservable.getInstance().addObserver(this);
        getCurrentLocation();

    }

    private void initMapView(Context ctx, Bundle savedInstanceState) {
        mapView.onCreate(ctx, savedInstanceState);
        mapView.showZoomControls(false);    //隐藏放大器按钮
        //上海为地图中心
        LatLng GEO_SHANGHAI = new LatLng(31.227, 121.481);
        MapStatusUpdate status2 = MapStatusUpdateFactory.newLatLng(GEO_SHANGHAI);
        mBaiduMap = mapView.getMap();
        mBaiduMap.setMapStatus(status2);

        // 设置缩放级别
        mBaiduMap.setMapStatus(
                MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(19).build()));
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        // 开启交通图层
        mBaiduMap.setTrafficEnabled(false);
        // 开启热力图层
        mBaiduMap.setBaiduHeatMapEnabled(false);

        IntentFilter iFilter = new IntentFilter();
        iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);
        iFilter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);
        mReceiver = new SDKReceiver();
        registerReceiver(mReceiver, iFilter);
    }

    /**
     * 启动位置服务
     */
    @SuppressLint("CheckResult")
    private void getCurrentLocation() {
        RxPermissions rxPermissions = new RxPermissions(this);
        rxPermissions.request(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION)
                .subscribe(granted -> {
                    if (granted) {
                        //有权限了。
                        startService(new Intent(MainActivity.this, WorkService.class));
                    } else {
                        //没有权限。
                        showToast("没有权限");
                    }
                });
    }

    /**
     * 接收service的信息。
     *
     * @param o
     * @param arg
     */
    @Override
    public void update(Observable o, Object arg) {
        L.d("update once");
        if (o instanceof MsgObservable) {
            if (arg instanceof Message) {
                Message msg = (Message) arg;
                switch (msg.what) {
                    case RunConstants.FIRST_LOCATION_MSG:
                        if (msg.obj instanceof MyLocationData && msg.obj != null) {
                            runOnUiThread(() -> firstGetLocation((MyLocationData) msg.obj));
                        }
                        break;
                    case RunConstants.RUN_FIRST_LOCATION_MSG:
                        if (msg.obj instanceof MyLocationData && msg.obj != null) {
                            runOnUiThread(() -> runGetFirstLocation((MyLocationData) msg.obj));
                        }
                        break;
                    case RunConstants.RUN_LOCATION_MSG:
                        if (msg.obj instanceof Information && msg.obj != null) {
                            runOnUiThread(() -> updateLocation((Information) msg.obj));
                        }
                        break;
                }
            }
        }
    }

    private void updateLocation(Information info) {
        //位置变化
        mPointListWithGps.clear();
        mPointListWithGps.addAll(info.mLocationList);
        mMoveGpsDataList.add(info.location);
        moveMap(mMoveGpsDataList);
        updateListenerView();
    }


    private void runGetFirstLocation(MyLocationData location) {

        mMoveGpsDataList.add(location);

        if (location != null) {
            MyLocationData locData = new MyLocationData.Builder().accuracy(40)
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(100).latitude(location.latitude).longitude(location.longitude)
                    .build();
            mBaiduMap.setMyLocationData(locData);
        }

        // 将地图移动到LatLng点。
        moveMap(mMoveGpsDataList);
        updateListenerView();
    }

    private void firstGetLocation(MyLocationData location) {
        mPointListWithGps.clear();

        mMoveGpsDataList.add(location);
        if (mMoveGpsDataList != null && mMoveGpsDataList.size() > 3) return;
        if (location != null) {
            MyLocationData locData = new MyLocationData.Builder().accuracy(40)
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(100).latitude(location.latitude).longitude(location.longitude)
                    .build();
            mBaiduMap.setMyLocationData(locData);
        }

        // 将地图移动到LatLng点。
        moveMap(mMoveGpsDataList);
        updateListenerView();
    }

    // 将地图移动到list的最后一个点。
    private void moveMap(LinkedList<MyLocationData> list) {
        MapStatusUpdate mMapStatusUpdate = mainPresenter.getMapStatusUpdate(list);
        if (mMapStatusUpdate != null) {
            mBaiduMap.setMapStatus(mMapStatusUpdate);
        } else {
            showToast("暂未拿到当前位置");
        }
    }

    private float mTotalDistance;
    private long mTotalTimes;
    private float speed;

    private void updateListenerView() {
        if (mMoveGpsDataList != null && mMoveGpsDataList.size() >= 1) {
            MyLocationData positionBean = mMoveGpsDataList.getLast();
//            mTvDis.setText("距离 ： " + mTotalDistance);
//            mTvV.setText("配速 ： " + positionBean.velocity + "m/s");
//            mTvTimes.setText("时间 ： " + getFormatTime(mTotalTimes));
            if (mPointListWithGps != null && mPointListWithGps.size() > 1) {
                mBaiduMap.clear();// 先将地图上的点清除。
                // 在地图上画线。
                OverlayOptions polylineOption = new PolylineOptions().points(mPointListWithGps)
                        .width(10).color(Color.RED);
                Polyline mVirtureRoad = (Polyline) mBaiduMap.addOverlay(polylineOption);
                // 在地图上画起始点。
                OverlayOptions markerOptions;
                markerOptions = new MarkerOptions().flat(true).anchor(0.5f, 0.5f)
                        .icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_positioning_big))
                        .position(mPointListWithGps.get(0));
                Marker mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions);
            }

            // 设置当前位置的蓝色的点。
            LatLng latLng = new LatLng(positionBean.latitude, positionBean.longitude);
            if (latLng != null) {
                MyLocationData locData = new MyLocationData.Builder().accuracy(40)
                        // 此处设置开发者获取到的方向信息，顺时针0-360
                        .direction(100).latitude(latLng.latitude).longitude(latLng.longitude)
                        .build();
                mBaiduMap.setMyLocationData(locData);
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        MsgObservable.getInstance().deleteObserver(this);
        if (mapView != null)
            mapView.onDestroy();
        unregisterReceiver(mReceiver);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_status) {
            if (item.getTitle().equals(getString(R.string.action_status_start))) {   //当前是停止状态
                // 开始记录位置
                WorkService.isRunStop = false;
                item.setTitle(R.string.action_status_stop);
            } else {
                // 停止记录位置
                WorkService.isRunStop = true;
                item.setTitle(R.string.action_status_start);
            }
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_map) {
            // Handle the camera action
        } else if (id == R.id.nav_raw) {
            startActivity(new Intent(this, RawDataActivity.class));
        } else if (id == R.id.nav_section) {
            startActivity(new Intent(this, SectionActivity.class));
        } else if (id == R.id.nav_time) {
            startActivity(new Intent(this, TimeActivity.class));
        }

        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onLoading(int type, boolean show) {

    }

    @Override
    public <M> void onData(int type, M data) {

    }

    @Override
    public void onError(int type, int code, String errMsg) {

    }

    @OnClick(R.id.iv_location)
    public void onViewClicked() {
        if (mMoveGpsDataList == null || mMoveGpsDataList.size() == 0)
            Snackbar.make(ivLocation, "Locating...", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        else
            moveMap(mMoveGpsDataList);
    }

    /**
     * 构造广播监听类，监听 SDK key 验证以及网络异常广播
     *
     * 百度sdk key 校验
     */
    public class SDKReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String s = intent.getAction();
            L.d("action: " + s);
            if (s.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR)) {
                showToast("key 验证出错! 请在 AndroidManifest.xml 文件中检查 key 设置");
            } else if (s.equals(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR)) {
                showToast("网络出错");
            }
        }
    }
}
